import BaseChart from './baseChart';
import chartActions from './charts';
import xAxisAction from './modules/xAxis';
import yAxisAction from './modules/yAxis';
import config from './config';
import * as _ from './utils';

class Chart extends BaseChart {
    elements = [];
    ctx = null;
    options = null;
    width = 300;
    height = 200;
    paddingTop = 20;
    paddingLeft = 20;
    paddingRight = 20;
    paddingBottom = 20;
    origin = {
        x: 20,
        y: 20,
        w: 260,
        h: 160,
    };
    title = null;

    constructor(_ctx, opts = null) {
        super();
        this.ctx = _ctx;
        if (opts) {
            this.setOption(opts);
        }
    }
    // 图标设置
    setOption(opts) {
        console.time('chart');
        // console.time('setOption');
        this.clear();
        if (!opts) return;
        this.options = opts;
        this.width = _.getObjProperty(opts, 'width', 300);
        this.height = _.getObjProperty(opts, 'height', 200);

        this.title = _.getObjProperty(opts, 'title', '');

        let grid = _.getGridOpt(opts || {}, this.width, this.height);
        this.paddingTop = grid.top;
        this.paddingLeft = grid.left;
        this.paddingRight = grid.right;
        this.paddingBottom = grid.bottom;
        this.origin = grid.origin;

        let series = _.getObjProperty(opts, 'series', []);

        let seriesType = _.getObjType(series);
        if ('object' === seriesType) {
            opts.series = [series];
        }
        this.series = opts.series;

        let barSeriesNum = 0;
        let allData = [];
        let hasAxis = false;
        let seriesDataLen = 0;
        this.series.forEach((s, i) => {
            if ('line' === s?.type) hasAxis = true;
            if ('bar' === s?.type) {
                hasAxis = true;
                barSeriesNum++;
            }
            let len = s?.data.length || 0;
            seriesDataLen = len > seriesDataLen ? len : seriesDataLen;
            let max = _.getMaxVal([...s.data]);
            allData.push(max);
            let color = _.getObjProperty(s, 'color', config.colors[i % 9]);
            s.color = color;
        });
        let xAxis = _.getObjProperty(opts, 'xAxis', {});
        if (xAxis.data && xAxis.data.length > 0) {
            seriesDataLen = xAxis.data.length;
        }

        let yAxis = _.getObjProperty(opts, 'yAxis', {});
        let yAxisWidth = 0;
        if (hasAxis && yAxis && xAxis) {
            let maxVal = _.getMaxVal(allData);
            let yAxisData = _.getAxisData(maxVal);
            yAxis.data = yAxisData;
            yAxis.xAxisLen = seriesDataLen;
            // 绘制y轴和辅助虚线
            let yAxisModule = yAxisAction(yAxis, grid.origin);
            yAxisWidth = yAxisModule.yOrigin.yAxisWidth;
            this.elements = [...this.elements, ...yAxisModule.elements];

            let xAxisData = _.getObjProperty(xAxis, 'data', []);
            let xAxisTitle = 0;
            if (xAxisData.length === 0) {
                while (seriesDataLen > xAxisTitle) {
                    xAxisTitle++;
                    xAxisData.push(xAxisTitle);
                }
            }
            xAxis.data = xAxisData;
            xAxis.yAxisWidth = yAxisWidth;
            // 绘制x轴
            let xAxisModule = xAxisAction(xAxis, grid.origin);
            this.elements = [...this.elements, ...xAxisModule.elements];
        }

        let barSeriesIndex = 1;
        this.series.forEach((s, i) => {
            let type = s.type;
            let opts = {
                xAxis,
                yAxis,
                origin: grid.origin,
                // color: config.colors[i % 9],
                lineWidth: s.lineWidth
            }
            if( 'bar' === type){
                opts.barSeriesNum = barSeriesNum;
                opts.barSeriesIndex = barSeriesIndex;
                barSeriesIndex++;
            }


            if (chartActions[type]) {
                let eles = chartActions[type](s, opts);
                this.elements = [...this.elements, ...eles];
            }
        });
        // console.timeEnd('setOption');
        this.draw();
    }
    // 图表刷新
    refresh() {
        this.clear();
        this.draw();
    }
    // 改变窗口大小
    resize(width = 300, height = 200) {
        let options = this.options;

        if (!options) return;
        options.width = width;
        options.height = height;
        this.setOption(options);
    }
    // 清除图表
    clear() {
        if (this.options) {
            let width = this.width || 300;
            let height = this.height || 100;
            this.elements = [];
            this.ctx.clearRect(0, 0, width, height);
        }
    }
    // 绘制图表
    draw() {
        // console.time('draw');
        this.elements.sort((a, b) => {
            let az = a.zIndex;
            let bz = b.zIndex;
            if (az < bz) {
                return -1;
            }
            if (az > bz) {
                return 1;
            }
            return 0;
        });
        console.log(this.elements);
        let ctx = this.ctx;
        this.elements.forEach((item) => {
            item.draw(ctx);
        });
        // this.elements.forEach((item) => {
        //     item.draw(ctx, true);
        //     // 260 550
        //     let res = item.isPointIn(ctx, 260, 550);
        //     // res && console.log(item);
        //     let res1 = item.isPointIn(ctx, 465, 262);
        //     // res1 && console.log(item);
        // });
        // console.timeEnd('draw');
        console.timeEnd('chart');
    }
}

export const init = function (ctx, opts = null) {
    return new Chart(ctx, opts);
};
export default Chart;
